const IS_DEBUG = true; // DEBUG开关

const debug = (...args) => {
  if (IS_DEBUG) {
    console.info('%c%s', 'color: blue; background: yellow; font-size: 11px;', ...args);
  }
  return;
};

import io from 'socket.io-client/dist/socket.io.js';
import mitt from '@/sheep/utils/mitt';
import chatApi from '@/app/chat/api';
import { callBackNotice, formatInput, formatMessage } from '../utils/socket.utils';
import { defineStore } from 'pinia';

// 重新连接尝试次数
const reconnectionAttempts = 5; //次
// 重新连接间隔时间
const reconnectionDelay = 10; // 秒
// let chatService = null;

const chat = defineStore({
  id: 'chat',
  state: () => ({
    config: {}, // 配置信息
    chatService: null, //
    sessionList: [], //会话列表
    servicerList: [], //客服列表
    sessionType: 'ing', //列表状态 // waiting| history
    customerOnLineList: [], // 会话中
    customerWaitingList: [], // 等待中
    customerHistoryList: [], // 已下线
    chatList: [], //会话信息
    commonWords: [], //常用语列表
    customerService: {}, //当前客服信息
    customerServiceIdentityList: [], //客服身份列表
    curCustomerInfo: null, //当前顾客信息
    chatHistoryPagination: {
      page: 0,
      list_rows: 10,
      last_id: 0,
      lastPage: 0,
      loadStatus: 'loadmore', //loadmore-加载前的状态，loading-加载中的状态，nomore-没有更多的状态
    },
    noticeType: '', //站内信类别
    noticeTypeList: [], // 站内信分类列表
    noticeList: [], //站内信列表
    connection: {
      status: '',
      attempts: 0,
      reconnectionAttempts,
      delay: 0,
      showTip: true,
    }, //
    isSendSucces: 0, // 是否发送成功 -1=发送中|0=发送成功|1发送失败
  }),
  getters: {
    // 获取除了自己的客服列表
    avaliableServicerList: (state) => {
      return state.servicerList.filter((item) => {
        return item.value != state.customerService.id;
      });
    },

    avaliableCustomerServiceIdentityList: (state) => {
      return state.customerServiceIdentityList.filter((item) => {
        return item.value != state.customerService.id;
      });
    },

    //总状态红点
    allChatDot: (state) => {
      return state.customerOnLineList.reduce((pre, cur) => {
        return pre + cur?.unread_num;
      }, state.customerWaitingList.length);
    },

    // 是否有等待中的客户
    hasWaiting: (state) => Boolean(state.customerWaitingList.length),

    // 站内信未读消息
    noticeUnreadNum: (state) => {
      return state.noticeTypeList.reduce((pre, cur) => {
        return pre + cur.unread_num;
      }, 0);
    },

    // 房间号
    rooms: (state) => state.config.default_rooms,
  },

  actions: {
    // 打开客服弹窗
    open_chat() {
      this.curCustomerInfo = this.customerOnLineList[0];
      this.customerOnLineList.length
        ? this.socket_change_customer_list({
            state: this.sessionType,
          })
        : mitt.emit('CHAT_HISTORY');
    },
    // 切换客服身份
    socket_change_customer_identity(data) {
      // 退出客服
      this.socket_logout_customer();
      // 登录客服
      let info = this.customerServiceIdentityList.filter((item) => data == item.value);
      this.socket_customer_login(info[0]);
      // 初始化客服
    },
    /**
     * @description 初始化chat请求
     */
    async chatInit() {
      const { error, data } = await chatApi.chatInit();
      debug('chatInit', data);
      if (error === 0) {
        this.config = data;
        this.socket_init(this.config.chat_domain);
      }
    },
    // 1.初始化socket
    async socket_init(connectionUrl, options) {
      this.connection.status = 'connecting';
      // 连接
      try {
        this.chatService = io(connectionUrl, {
          reconnection: true, // 默认 true    是否断线重连
          reconnectionAttempts: reconnectionAttempts, // 默认无限次   断线尝试次数
          reconnectionDelay: reconnectionDelay * 1000, // 默认 1000，进行下一次重连的间隔。
          reconnectionDelayMax: reconnectionDelay * 1000, // 默认 5000， 重新连接等待的最长时间 默认 5000
          randomizationFactor: 0.5, // 默认 0.5 [0-1]，随机重连延迟时间
          timeout: 20000, // 默认 20s
          transports: ['websocket', 'polling'], // websocket | polling,
          ...options,
        });
      } catch (error) {
        debug('Socket连接错误', error);
      }

      // 连接成功
      this.chatService.on('connect', (res) => {
        debug('connect', res);
        this.connection.status = 'connect';
        this.socket_connection();
      });

      // 监听会话
      this.chatService.on('message', (res) => {
        debug('message', res);
        if (res.error == 0) {
          audioPlay('chat');
          const { message, sender } = res.data;
          if (this.curCustomerInfo && this.curCustomerInfo?.session_id == sender.session_id) {
            // 如果是当前会话，数字角标不增加，chatList，push
            this.chatList.push(formatMessage(message));
            mitt.emit('CHAT_BOTTOM');
          } else {
            // 非当前会话，顾客角标+1
            const index = this.customerOnLineList.findIndex(
              (item) => item.session_id == sender.session_id,
            );
            if (~index) this.customerOnLineList[index].unread_num += 1;
          }
        }
      });

      // 用户上线
      this.chatService.on('customer_online', (res) => {
        res.error == 0 && this.socket_change_customer_state(res.data);
      });

      // 用户下线
      this.chatService.on('customer_offline', (res) => {
        res.error == 0 && this.socket_change_customer_state(res.data);
      });

      // 用户被接入
      this.chatService.on('customer_accessed', (res) => {
        if (res.error == 0) {
          const { session_id, chat_user } = res.data;
          const index = this.customerWaitingList.findIndex((item) => item.session_id == session_id);
          index >= 0 && this.customerWaitingList.splice(index, 1);
          if (this.sessionType == 'waiting') {
            this.curCustomerInfo =
              this.customerWaitingList.length >= 1
                ? this.customerWaitingList[0]
                : this.socket_reset();
          }
        }
      });

      // 新用户接入
      this.chatService.on('customer_access', (res) => {
        if (res.error == 0) {
          const { session_id, chat_user } = res.data;
          const index = this.customerOnLineList.findIndex((item) => item.session_id == session_id);
          // 如果用户存在，修改会话中用户状态
          if (index >= 0) {
            this.customerOnLineList[index].status = chat_user.status;
          } else {
            // 如果用户不存在
            this.customerOnLineList.unshift(chat_user);
            // 如果当前会话列表有且只有一个新增会话
            if (this.customerOnLineList.length > 0 && this.sessionType == 'ing') {
              this.curCustomerInfo = chat_user;
              this.socket_customer_history();
            }
            // 如果在waitin列表，接入后
          }

          // TODO: 先不自动跳转，手动接入，自动接入无法区分；
          // state.sessionType = 'ing';
          // state.sessionList = state.customerOnLineList;
          // state.curCustomerInfo = chat_user
          // this.commit("chat/socket/SOCKET_CUSTOMER_HISTORY")

          callBackNotice(res);
        }
      });

      // 更新客服列表customer_service_update
      this.chatService.on('customer_service_update', (res) => {
        if (res.error == 0) {
          this.servicerList = res.data.customer_services.map((item) => ({
            label: item.name,
            value: item.id,
          }));
        }
      });

      // 新顾客等待，更新等待列表
      this.chatService.on('customer_waiting', (res) => {
        if (res.error == 0) {
          this.customerWaitingList = res.data.waitings;
          audioPlay('chat');
          if (this.sessionType == 'waiting') {
            this.sessionList = res.data.waitings;
            this.curCustomerInfo = this.sessionList.length
              ? res.data.waitings[0]
              : this.socket_reset();
          }
        }
      });

      // 新的站内信
      this.chatService.on('notification', (res) => {
        if (res.error == 0) {
          audioPlay('notice');
          if (this.noticeType == res.data.notification_type) {
            this.noticeList.unshift(res.data);
          } else {
            this.noticeTypeList.map((item) => {
              if (item.value == res.data.notification_type) {
                item.unread_num += 1;
              }
            });
          }
        }
      });

      // 自定义错误
      this.chatService.on('custom_error', (error) => {
        callBackNotice(error, true);
      });

      this.chatService.on('error', (error) => {
        this.connection.status = 'error';
        debug('error', error);
        mitt.emit('CHAT_BOTTOM');
        mitt.emit('CHAT_HISTORY');
      });

      // 连接失败
      this.chatService.on('connect_error', (error) => {
        debug('connect_error:', error);
        mitt.emit('CHAT_BOTTOM');
        mitt.emit('CHAT_HISTORY');
      });

      // 连接超时
      this.chatService.on('connect_timeout', (error) => {
        debug('connect_timeout:', error);
      });

      // 断开连接
      this.chatService.on('disconnect', (error) => {
        debug('disconnect:', error);
      });
      // 服务重启重连上reconnect
      this.chatService.on('reconnect', (error) => {
        debug('disconnect:', error);
      });

      // 尝试重连
      this.chatService.on('reconnect_attempt', (counter) => {
        debug('reconnect_attempt', counter);
        this.connection.status = 'reconnect_attempt';
      });

      // 重新连接中
      this.chatService.on('reconnecting', (counter) => {
        debug('reconnecting', counter);
        this.connection.status = 'reconnecting';
        this.connection.attempts = counter;
      });

      // 重连失败
      this.chatService.on('reconnect_error', (error) => {
        debug('reconnect_error', error);
        if (this.connection.attempts >= this.connection.reconnectionAttempts) {
          return;
        }
        this.connection.status = 'reconnect_error';
        // 设置倒计时
        this.connection.delay = reconnectionDelay;
        const timer = setInterval(() => {
          this.connection.delay -= 1;
          if (this.connection.delay <= 1) {
            clearInterval(timer);
          }
        }, 1000);
      });

      // 重连失败 达到最大重试次数
      this.chatService.on('reconnect_failed', () => {
        debug('reconnect_failed');
        this.connection.status = 'reconnect_failed';
        this.isSendSucces = 1;
      });

      // 与服务器连接失败
      this.chatService.on('connect_failed', (error) => {
        debug('connect_failed', error);
      });
    },

    // socket 连接
    socket_connection(token) {
      this.chatService.emit(
        'connection',
        {
          auth: 'admin',
          token: this.config.token,
        },
        (res) => {
          debug('socket_connection:', res);
          if (res.error == 0) {
            this.socket_check_identify();
          }
        },
      );
    },
    // 检测是否是客服
    socket_check_identify() {
      this.chatService.emit('check_identify', {}, (res) => {
        debug('socket_check_identify:', res);
        if (res.error == 0) {
          this.socket_customer_login(res.data.customer_services[0]);
          this.customerServiceIdentityList = res.data.customer_services.map((item) => ({
            label: item.name,
            value: item.id,
            room_id: item.room_id,
          }));
        }
      });
    },

    // 客服登录
    socket_customer_login(data) {
      this.chatService.emit(
        'customer_service_login',
        {
          room_id: data?.room_id || 'admin',
        },
        (res) => {
          debug('customer_service_login:', res);
          if (res.error == 0) {
            this.customerService = res.data.customer_service;
            this.commonWords = res.data.common_words;
            this.socket_customer_init();
          }
          callBackNotice(res);
        },
      );
    },
    // 初始化客服
    socket_customer_init() {
      this.chatService.emit('customer_service_init', {}, (res) => {
        if (res.error == 0) {
          this.customerOnLineList = res.data.onlines;
          this.customerWaitingList = res.data.waitings;
          if (this.customerWaitingList.length > 0) {
            // audioPlay('chat');
          }
          this.customerHistoryList = res.data.histories;
          this.sessionList = res.data.onlines;
          this.socket_change_customer_list({
            state: this.sessionType,
          });
        }
      });
    },
    // 切换会话列表
    socket_change_customer_list(data) {
      this.socket_reset();
      this.sessionType = data.state;
      switch (data.state) {
        case 'ing':
          this.sessionList = this.customerOnLineList;
          break;
        case 'waiting':
          this.sessionList = this.customerWaitingList;
          break;
        case 'history':
          this.sessionList = this.customerHistoryList;
          break;
        default:
          break;
      }
      if (!data.type) {
        // 默认显示第一个人的会话信息
        this.sessionList.length && this.socket_change_customer_info(data.index || 0);
      }
    },

    // 修改顾客信息，获取历史记录
    socket_change_customer_info(index = 0) {
      this.socket_reset();
      this.curCustomerInfo = this.sessionList[index];
      if (this.sessionList[index]) {
        this.sessionList[index].unread_num = 0;
      }
      this.socket_customer_history();
    },

    // 重置
    socket_reset() {
      this.curCustomerInfo = null;
      this.chatList = [];
      this.chatHistoryPagination = {
        page: 0,
        list_rows: 10,
        last_id: 0,
        totalPage: 0,
        loadStatus: 'loadmore',
      };
    },
    // 退出客服
    socket_logout_customer() {
      debug('socket_logout_start');
      this.chatService.emit('customer_service_logout', {}, (res) => {
        debug('socket_logout_res:', res);
      });
    },
    // 获取用户历史消息
    socket_customer_history() {
      if (!this.curCustomerInfo) return mitt.emit('CHAT_HISTORY');
      this.chatHistoryPagination.loadStatus = 'loading';
      this.chatHistoryPagination.page += 1;
      this.chatService.emit(
        'messages',
        {
          session_id: this.curCustomerInfo?.session_id || 0,
          ...this.chatHistoryPagination,
        },
        (res) => {
          if (res.error == 0) {
            this.chatHistoryPagination.total = res.data.messages.total;
            this.chatHistoryPagination.lastPage = res.data.messages.last_page;
            this.chatHistoryPagination.page = res.data.messages.current_page;
            if (res.data.messages.current_page == 1) {
              this.chatList = [];
            }
            res.data.messages.data.forEach((item) => {
              this.chatList.unshift(formatMessage(item));
            });
            this.chatHistoryPagination.loadStatus =
              this.chatHistoryPagination.page < this.chatHistoryPagination.lastPage
                ? 'loadmore'
                : 'nomore';
            this.chatHistoryPagination.page == 1 && mitt.emit('CHAT_BOTTOM');
            if (this.chatHistoryPagination.last_id == 0) {
              this.chatHistoryPagination.last_id = res.data.messages.data.length
                ? res.data.messages.data[0].id
                : 0;
            }
            mitt.emit('CHAT_HISTORY');
          }
        },
      );
    },

    // 修改顾客状态
    socket_change_customer_state(data) {
      const { session_id, chat_user } = data;
      let waitingIndex = -1,
        onlineIndex = -1,
        historyIndex = -1;

      if (this.customerWaitingList.length) {
        waitingIndex = this.customerWaitingList.findIndex((item) => item.session_id == session_id);
        if (waitingIndex >= 0) {
          this.customerWaitingList[waitingIndex].status = chat_user.status;
        }
      }
      if (this.customerOnLineList.length) {
        onlineIndex = this.customerOnLineList.findIndex((item) => item.session_id == session_id);
        if (onlineIndex >= 0) {
          this.customerOnLineList[onlineIndex].status = chat_user.status;
        }
      }
      if (this.customerHistoryList.length) {
        historyIndex = this.customerHistoryList.findIndex((item) => item.session_id == session_id);
        if (historyIndex >= 0) {
          this.customerHistoryList[historyIndex].status = chat_user.status;
        }
      }
    },
    // 发送消息
    socket_send(data) {
      // 给会话列表
      this.isSendSucces = -1;
      this.chatList.push(data);
      // 给socket
      this.chatService.emit(
        'message',
        {
          session_id: this.curCustomerInfo?.session_id || 0,
          message: formatInput(data),
        },
        (res) => {
          this.isSendSucces = res.error;
        },
      );
    },

    // 断开，删除顾客
    socket_change_customer(sessionId, index, customerState, is_del_record) {
      if (customerState == 'ing') {
        this.chatService.emit('break_customer', { session_id: sessionId }, (res) => {
          if (res.error == 0) {
            this.customerOnLineList.splice(index, 1);
            this.socket_reset();
          }
          callBackNotice(res);
        });
      }
      if (customerState == 'history') {
        this.chatService.emit('del_customer', { session_id: sessionId, is_del_record }, (res) => {
          if (res.error == 0) {
            this.customerHistoryList.splice(index, 1);
            this.socket_reset();
          }
          callBackNotice(res);
        });
      }
    },

    // 切换客服状态
    socket_change_service_state(serviceState) {
      let that = this;
      switch (serviceState) {
        case 'onLine':
          this.chatService.emit('customer_service_online', {}, (res) => {
            changeBack(res);
          });
          break;
        case 'busy':
          this.chatService.emit('customer_service_busy', {}, (res) => {
            changeBack(res);
          });
          this.sessionList = this.customerWaitingList;
          break;
        case 'leave':
          this.chatService.emit('customer_service_offline', {}, (res) => {
            changeBack(res);
          });
          this.sessionList = this.customerHistoryList;
          break;
        default:
          break;
      }
      // 切换回调
      function changeBack(res) {
        if (res.error == 0) that.customerService = res.data.customer_service;
        callBackNotice(res);
      }
    },

    // access 接入客户，会触发监听接入，被接入
    socket_customer_access(index) {
      this.chatService.emit(
        'access',
        { session_id: this.curCustomerInfo?.session_id },
        (res) => {},
      );
    },

    showConnectionTip(status) {
      this.connection.showTip = status;
    },

    // 更新站内信列表
    notice_list(data) {
      this.noticeList = [...this.noticeList, ...data];
    },
    notice_list_clear(data) {
      this.noticeList = [];
    },
    // 更改站内信dot
    notice_read(type) {
      this.noticeType = type;
      this.noticeTypeList.map((item) => {
        if (item.value == type) {
          item.unread_num = 0;
        }
      });
    },
    notice_replace({ index, data }) {
      this.noticeList[index] = data;
    },

    // transfer 转接顾客
    socket_transfer(customer_service_id) {
      this.chatService.emit(
        'transfer',
        {
          session_id: this.curCustomerInfo?.session_id,
          customer_service_id,
        },
        (res) => {
          callBackNotice(res);
          if (res.error == 0) {
            const index = this.customerOnLineList.findIndex(
              (item) => item.session_id == this.curCustomerInfo?.session_id,
            );
            this.customerOnLineList.splice(index, 1);
            this.socket_reset();
          }
        },
      );
    },
    // 更新站内信typ
    notice_type(data) {
      this.noticeTypeList = data.notification_type;
    },
  },
});

function audioPlay(type) {
  let ex = new Audio(`./static/images/chat/${type}.mp3`);
  if (ex?.hasOwnProperty('play')) {
    ex.play();
  }
}

export default chat;
